#ifndef _WX_WIZARD_H_
#define _WX_WIZARD_H_

#include "wx/defs.h"

#if wxUSE_WIZARDDLG

#include "wx/dialog.h"      // the base class
#include "wx/panel.h"       // ditto
#include "wx/event.h"       // wxEVT_XXX constants
#include "wx/bitmap.h"

#define wxWIZARD_EX_HELPBUTTON   0x00000010

class wxWizard;

class wxWizardPage : public wxPanel {
  public:
    wxWizardPage() { Init(); }
    wxWizardPage( wxWizard *parent, const wxBitmap& bitmap = wxNullBitmap, const wxChar* resource = NULL );
    bool Create( wxWizard *parent, const wxBitmap& bitmap = wxNullBitmap, const wxChar* resource = NULL );
    virtual wxWizardPage *GetPrev() const = 0;
    virtual wxWizardPage *GetNext() const = 0;
    virtual wxBitmap GetBitmap() const { return m_bitmap; }

    #if wxUSE_VALIDATORS
    // Override the base functions to allow a validator to be assigned to this page.
    virtual bool TransferDataToWindow() {
      return GetValidator() ? GetValidator()->TransferToWindow()
             : wxPanel::TransferDataToWindow();
    }

    virtual bool TransferDataFromWindow() {
      return GetValidator() ? GetValidator()->TransferFromWindow()
             : wxPanel::TransferDataFromWindow();
    }

    virtual bool Validate() {
      return GetValidator() ? GetValidator()->Validate( this )
             : wxPanel::Validate();
    }
    #endif // wxUSE_VALIDATORS

  protected:
    // common part of ctors:
    void Init();

    wxBitmap m_bitmap;

  private:
    DECLARE_DYNAMIC_CLASS_NO_COPY( wxWizardPage )
};

class wxWizardPageSimple : public wxWizardPage {
  public:
    wxWizardPageSimple() { Init(); }

    // ctor takes the previous and next pages
    wxWizardPageSimple( wxWizard *parent, wxWizardPage *prev = ( wxWizardPage * )NULL,
                        wxWizardPage *next = ( wxWizardPage * )NULL, const wxBitmap& bitmap = wxNullBitmap,
                        const wxChar* resource = NULL ) {
      Create( parent, prev, next, bitmap, resource );
    }

    bool Create( wxWizard *parent = NULL, // let it be default ctor too
                 wxWizardPage *prev = ( wxWizardPage * )NULL,
                 wxWizardPage *next = ( wxWizardPage * )NULL,
                 const wxBitmap& bitmap = wxNullBitmap,
                 const wxChar* resource = NULL ) {
      m_prev = prev;
      m_next = next;
      return wxWizardPage::Create( parent, bitmap, resource );
    }

    // the pointers may be also set later - but before starting the wizard
    void SetPrev( wxWizardPage *prev ) { m_prev = prev; }
    void SetNext( wxWizardPage *next ) { m_next = next; }

    // a convenience function to make the pages follow each other
    static void Chain( wxWizardPageSimple *first, wxWizardPageSimple *second ) {
      wxCHECK_RET( first && second,
                   wxT( "NULL passed to wxWizardPageSimple::Chain" ) );
      first->SetNext( second );
      second->SetPrev( first );
    }

    // base class pure virtuals
    virtual wxWizardPage *GetPrev() const;
    virtual wxWizardPage *GetNext() const;

  private:
    // common part of ctors:
    void Init() {
      m_prev = m_next = NULL;
    }

    wxWizardPage *m_prev,*m_next;

    DECLARE_DYNAMIC_CLASS_NO_COPY( wxWizardPageSimple )
};

class wxWizardBase : public wxDialog {
  public:
    wxWizardBase() { }

    // executes the wizard starting from the given page, returns true if it was
    // successfully finished, false if user cancelled it
    virtual bool RunWizard( wxWizardPage *firstPage ) = 0;

    // get the current page (NULL if RunWizard() isn't running)
    virtual wxWizardPage *GetCurrentPage() const = 0;
    virtual void SetPageSize( const wxSize& size ) = 0;
    virtual wxSize GetPageSize() const = 0;
    virtual void FitToPage( const wxWizardPage *firstPage ) = 0;

    // Adding pages to page area sizer enlarges wizard
    virtual wxSizer *GetPageAreaSizer() const = 0;

    // Set border around page area. Default is 0 if you add at least one
    // page to GetPageAreaSizer and 5 if you don't.
    virtual void SetBorder( int border ) = 0;

    // the methods below may be overridden by the derived classes to provide
    // custom logic for determining the pages order

    virtual bool HasNextPage( wxWizardPage *page ) { return page->GetNext() != NULL; }

    virtual bool HasPrevPage( wxWizardPage *page ) { return page->GetPrev() != NULL; }

    /// Override these functions to stop InitDialog from calling TransferDataToWindow
    /// for _all_ pages when the wizard starts. Instead 'ShowPage' will call
    /// TransferDataToWindow for the first page only.
    bool TransferDataToWindow() { return true; }
    bool TransferDataFromWindow() { return true; }
    bool Validate() { return true; }

  private:
    DECLARE_NO_COPY_CLASS( wxWizardBase )
};

// include the real class declaration
#include "wx/generic/wizard.h"

class wxWizardEvent : public wxNotifyEvent {
  public:
    wxWizardEvent( wxEventType type = wxEVT_NULL,int id = wxID_ANY,bool direction = true,wxWizardPage* page = NULL );
    bool GetDirection() const { return m_direction; }

    wxWizardPage*   GetPage() const { return m_page; }

  private:
    bool m_direction;
    wxWizardPage*    m_page;

    DECLARE_DYNAMIC_CLASS( wxWizardEvent )
    DECLARE_NO_COPY_CLASS( wxWizardEvent )
};

BEGIN_DECLARE_EVENT_TYPES()
DECLARE_EXPORTED_EVENT_TYPE( wxEVT_WIZARD_PAGE_CHANGED, 900 )
DECLARE_EXPORTED_EVENT_TYPE( wxEVT_WIZARD_PAGE_CHANGING, 901 )
DECLARE_EXPORTED_EVENT_TYPE( wxEVT_WIZARD_CANCEL, 902 )
DECLARE_EXPORTED_EVENT_TYPE( wxEVT_WIZARD_HELP, 903 )
DECLARE_EXPORTED_EVENT_TYPE( wxEVT_WIZARD_FINISHED, 903 )
DECLARE_EXPORTED_EVENT_TYPE( wxEVT_WIZARD_PAGE_SHOWN, 904 )
END_DECLARE_EVENT_TYPES()

typedef void ( wxEvtHandler::*wxWizardEventFunction )( wxWizardEvent& );

#define wxWizardEventHandler(func) \
  (wxObjectEventFunction)(wxEventFunction)wxStaticCastEvent(wxWizardEventFunction, &func)

#define wx__DECLARE_WIZARDEVT(evt, id, fn) \
  wx__DECLARE_EVT1(wxEVT_WIZARD_ ## evt, id, wxWizardEventHandler(fn))

// notifies that the page has just been changed (can't be vetoed)
#define EVT_WIZARD_PAGE_CHANGED(id, fn) wx__DECLARE_WIZARDEVT(PAGE_CHANGED, id, fn)

// the user pressed "<Back" or "Next>" button and the page is going to be
// changed - unless the event handler vetoes the event
#define EVT_WIZARD_PAGE_CHANGING(id, fn) wx__DECLARE_WIZARDEVT(PAGE_CHANGING, id, fn)

// the user pressed "Cancel" button and the wizard is going to be dismissed -
// unless the event handler vetoes the event
#define EVT_WIZARD_CANCEL(id, fn) wx__DECLARE_WIZARDEVT(CANCEL, id, fn)

// the user pressed "Finish" button and the wizard is going to be dismissed -
#define EVT_WIZARD_FINISHED(id, fn) wx__DECLARE_WIZARDEVT(FINISHED, id, fn)

// the user pressed "Help" button
#define EVT_WIZARD_HELP(id, fn) wx__DECLARE_WIZARDEVT(HELP, id, fn)

// the page was just shown and laid out
#define EVT_WIZARD_PAGE_SHOWN(id, fn) wx__DECLARE_WIZARDEVT(PAGE_SHOWN, id, fn)

#endif // wxUSE_WIZARDDLG

#endif // _WX_WIZARD_H_
